package keni.html.android.framework.offlineContentProvider.database;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;



import keni.html.android.framework.metadata.DataModel;
import keni.html.android.framework.metadata.FieldMetadata;
import keni.html.android.framework.util.Constants;
import keni.html.android.framework.util.IVertex;
import keni.html.android.framework.util.NamedGraphNode;
import keni.html.android.framework.util.TopologicalSortAlgo;

public class DatabaseMetadata {
private List<DatatableMetadata> orderedDataTables=new ArrayList<DatatableMetadata>();
private Map<String, DatatableMetadata> tables=new Hashtable<String, DatatableMetadata>();

public List<DatatableMetadata> getTables() {
	List<DatatableMetadata> tempTables=new ArrayList<DatatableMetadata>();
	for (Map.Entry<String, DatatableMetadata> tableEntry : tables.entrySet()) {
		tempTables.add(tableEntry.getValue());
	}
	return tempTables;
}

public  List<DatatableMetadata> getOrderedDataTables() {
	 Map<String,NamedGraphNode> nodesMap=new Hashtable<String,NamedGraphNode>();
	 if(orderedDataTables.size()>0)
	 {
		 return orderedDataTables;
	 }
	 for (DatatableMetadata table : getTables()) {
		 NamedGraphNode currentNode=new NamedGraphNode();
		 currentNode.setName(table.tableName);
		 nodesMap.put(table.tableName, currentNode);
		 for (String parentTableName : table.getParentTabls()) {
			NamedGraphNode parentNode=null;
			if(table.tableName.equalsIgnoreCase(parentTableName))
			{
				continue;
			}
			
			if(nodesMap.containsKey(parentTableName))
			{
				parentNode=nodesMap.get(parentTableName);
			}
			else
			{
				parentNode=new NamedGraphNode();
				parentNode.setName(parentTableName);
				nodesMap.put(parentTableName, parentNode);
			}
			parentNode.AddDependent(currentNode);
		}
	}
	 NamedGraphNode[] graphNodes=new NamedGraphNode[nodesMap.size()];
	 int index=0;
	 for (Map.Entry<String, NamedGraphNode> nodesEntry : nodesMap.entrySet()) {
		 graphNodes[index]=nodesEntry.getValue();
		 index++;
	}
	 
	 IVertex[] orderedGraphNodes= TopologicalSortAlgo.Sort(graphNodes); 
	 for (IVertex iVertex : orderedGraphNodes) {
		 String dataTableName=((NamedGraphNode)iVertex).getName();
		if(tables.containsKey(dataTableName))
		 orderedDataTables.add(tables.get(dataTableName));
	}
	return orderedDataTables;
}


public List<JSONObject> getUpdateCommand(String jsonFormatData) throws JSONException {
	JSONObject inputData=new JSONObject(jsonFormatData);
	Map<String, JSONObject> commandMap=new Hashtable<String, JSONObject>();
	JSONArray dataArray= inputData.getJSONArray(Constants.JsonObjectKeys.DATA);
	for (int i = 0; i < dataArray.length(); i++) {
	JSONObject data=dataArray.getJSONObject(i);
	Iterator<String> keysIterator=data.keys();	
	while (keysIterator.hasNext()) {
		String key = keysIterator.next();
		FieldMetadata field=indexableFields.get(key);
		String dataSourceName=field.getDataSourceName();
		if(!commandMap.containsKey(dataSourceName))
		{
			JSONObject tempCommandJsonObject=new JSONObject();
			JSONArray tempdataArray=new JSONArray();
			for (int j = 0; j < dataArray.length(); j++) {
				tempdataArray.put(j,new JSONObject());
				
			}
			tempCommandJsonObject.put(Constants.JsonObjectKeys.DATASOURCENAME, dataSourceName);
			tempCommandJsonObject.put(Constants.JsonObjectKeys.DATA, tempdataArray);
			commandMap.put(dataSourceName, tempCommandJsonObject);
		}
		JSONObject dataRecordJsonObject=commandMap.get(dataSourceName).getJSONArray(Constants.JsonObjectKeys.DATA).getJSONObject(i);
		 
		dataRecordJsonObject.put(field.getElementId(), data.get(key));
		
	}
		
	}
	
	List<JSONObject> orderedCommandJsonObjects=new ArrayList<JSONObject>();
	
	for (DataModel dataModel : getOrderedDataModel()) {
		orderedCommandJsonObjects.add(commandMap.get(dataModel.dataSourceName));
	}
	return orderedCommandJsonObjects;
}



public List<JSONObject> getInsertCommand(String jsonFormatData) throws JSONException{
	JSONObject inputData=new JSONObject(jsonFormatData);
	Map<String, JSONObject> commandMap=new Hashtable<String, JSONObject>();
	JSONArray dataArray= inputData.getJSONArray(Constants.JsonObjectKeys.DATA);
	for (int i = 0; i < dataArray.length(); i++) {
	JSONObject data=dataArray.getJSONObject(i);
	Iterator<String> keysIterator=data.keys();	
	while (keysIterator.hasNext()) {
		String key = keysIterator.next();
		FieldMetadata field=indexableFields.get(key);
		String dataSourceName=field.getDataSourceName();
		if(!commandMap.containsKey(dataSourceName))
		{
			JSONObject tempCommandJsonObject=new JSONObject();
			JSONArray tempdataArray=new JSONArray();
			for (int j = 0; j < dataArray.length(); j++) {
				tempdataArray.put(j,new JSONObject());
				
			}
			tempCommandJsonObject.put(Constants.JsonObjectKeys.DATASOURCENAME, dataSourceName);
			tempCommandJsonObject.put(Constants.JsonObjectKeys.DATA, tempdataArray);
			commandMap.put(dataSourceName, tempCommandJsonObject);
		}
		JSONObject dataRecordJsonObject=commandMap.get(dataSourceName).getJSONArray(Constants.JsonObjectKeys.DATA).getJSONObject(i);
		 
		dataRecordJsonObject.put(field.getElementId(), data.get(key));
		
	}
		
	}
	
	List<JSONObject> orderedCommandJsonObjects=new ArrayList<JSONObject>();
	
	for (DataModel dataModel : getOrderedDataModel()) {
		orderedCommandJsonObjects.add(commandMap.get(dataModel.dataSourceName));
	}
	return orderedCommandJsonObjects;
}



public List<JSONObject> getDeleteCommand(String jsonFormatData) throws JSONException{
	JSONObject inputData=new JSONObject(jsonFormatData);
	Map<String, JSONObject> commandMap=new Hashtable<String, JSONObject>();
	JSONArray dataArray= inputData.getJSONArray(Constants.JsonObjectKeys.DATA);
	for (int i = 0; i < dataArray.length(); i++) {
	JSONObject data=dataArray.getJSONObject(i);
	Iterator<String> keysIterator=data.keys();	
	while (keysIterator.hasNext()) {
		String key = keysIterator.next();
		FieldMetadata field=indexableFields.get(key);
		String dataSourceName=field.getDataSourceName();
		if(!commandMap.containsKey(dataSourceName))
		{
			JSONObject tempCommandJsonObject=new JSONObject();
			JSONArray tempdataArray=new JSONArray();
			for (int j = 0; j < dataArray.length(); j++) {
				tempdataArray.put(j,new JSONObject());
				
			}
			tempCommandJsonObject.put(Constants.JsonObjectKeys.DATASOURCENAME, dataSourceName);
			tempCommandJsonObject.put(Constants.JsonObjectKeys.DATA, tempdataArray);
			commandMap.put(dataSourceName, tempCommandJsonObject);
		}
		JSONObject dataRecordJsonObject=commandMap.get(dataSourceName).getJSONArray(Constants.JsonObjectKeys.DATA).getJSONObject(i);
		 
		dataRecordJsonObject.put(field.getElementId(), data.get(key));
		
	}
		
	}
	
	List<JSONObject> orderedCommandJsonObjects=new ArrayList<JSONObject>();
	List<DataModel> tempOrderedDataModels=getOrderedDataModel();
	int index=tempOrderedDataModels.size();
	for (int i = 0; i < tempOrderedDataModels.size(); i++) {
		orderedCommandJsonObjects.add(commandMap.get(tempOrderedDataModels.get(index-1-i).dataSourceName));
	}

	return orderedCommandJsonObjects;
}




